package interpreter.biback.domain

import java.util.concurrent.ConcurrentHashMap

import biback.domain.DomainEvent
import biback.utils._
import cats.Monad

import scala.collection.JavaConverters._
import scala.collection.concurrent.{Map => XMap}
import scala.reflect.ClassTag

class RegistryMock[F[_]](es: Map[String, List[DomainEvent]] = Map.empty[String, List[DomainEvent]]) extends RegistryAlgebra.Service[F] {
  val entities: XMap[String, DomainEntity] = new ConcurrentHashMap[String, DomainEntity]().asScala
  def refFor[P <: DomainEntity : ClassTag](rootId: String)(implicit F: Monad[F]): ErrOrF[P] = {
    val entityClass = implicitly[ClassTag[P]].runtimeClass.asInstanceOf[Class[P]]
    val key = entityClass.getName + "#" + rootId
    val entity = entities.getOrElseUpdate(key, replay[P](entityClass, key))
    resultF(entity.asInstanceOf[P])
  }
  def replay[P <: DomainEntity : ClassTag](entityClass: Class[P], key: String): DomainEntity = {
    val e = entityClass.newInstance().asInstanceOf[DomainEntity]
    e.entityId = key
    es.get(key).foreach { events =>
      e.replay(events.asInstanceOf[List[e.Event]])
    }
    e
  }
}

